/*
 * Copyright (c) 2022 PATEO CONNECT+ (Nanjing) Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "voice_cloud_loader.h"
#include "voice_assistant_log.h"
#include <dlfcn.h>

namespace OHOS {
namespace CarVoiceAssistant {

    typedef IVoiceCloudManager* CreateVoiceCloudManagerFuncPointer();
    typedef void DestoryVoiceCloudManagerFuncPointer(IVoiceCloudManager* manager);

    void* g_voicecloud = nullptr;
    CreateVoiceCloudManagerFuncPointer* g_createVoiceCloudManagerFunc = nullptr;
    DestoryVoiceCloudManagerFuncPointer* g_destoryVoiceCloudManagerFunc = nullptr;
    void LoadVoiceCloud()
    {
        if (g_voicecloud) {
            return;
        }

        void* voiceCloud = dlopen("/system/lib/libvoicecloud.z.so", RTLD_LAZY);
        if (!voiceCloud) {
            VOICE_ASSISTANT_LOGI("dlopen /system/lib/libvoicecloud.z.so failed");
            voiceCloud = dlopen("/system/lib/module/libvoicecloud.z.so", RTLD_LAZY);
            if (!voiceCloud) {
                VOICE_ASSISTANT_LOGI("dlopen /system/lib/module/libvoicecloud.z.so failed");
            }
        }

        if (voiceCloud) {
            VOICE_ASSISTANT_LOGI("dlopen libvoicecloud.z.so success");
            g_voicecloud = voiceCloud;
        }
    }

    IVoiceCloudManager* CreateVoiceCloudManager()
    {
        if (g_voicecloud == nullptr) {
            LoadVoiceCloud();
        }

        if (g_voicecloud == nullptr) {
            return nullptr;
        }

        if (g_createVoiceCloudManagerFunc) {
            return g_createVoiceCloudManagerFunc();
        }

        CreateVoiceCloudManagerFuncPointer* createFunc = (CreateVoiceCloudManagerFuncPointer*)dlsym(g_voicecloud, "CreateVoiceCloudManager");

        if (!createFunc) {
            VOICE_ASSISTANT_LOGI("CreateVoiceCloudManager dlsym CreateVoiceCloudManager failed");
            return nullptr;
        }

        g_createVoiceCloudManagerFunc = createFunc;

        return g_createVoiceCloudManagerFunc();
    }

    void DestoryVoiceCloudManager(IVoiceCloudManager* manager)
    {
        if (g_voicecloud == nullptr) {
            LoadVoiceCloud();
        }

        if (g_voicecloud == nullptr) {
            return;
        }

        if (g_destoryVoiceCloudManagerFunc) {
            g_destoryVoiceCloudManagerFunc(manager);
            return;
        }

        DestoryVoiceCloudManagerFuncPointer* destoryFunc = (DestoryVoiceCloudManagerFuncPointer*)dlsym(g_voicecloud, "DestoryVoiceCloudManager");

        if (!destoryFunc) {
            VOICE_ASSISTANT_LOGI("DestoryVoiceCloudManager dlsym DestoryVoiceCloudManager failed");
            return;
        }

        g_destoryVoiceCloudManagerFunc = destoryFunc;

        g_destoryVoiceCloudManagerFunc(manager);
    }
}
}
